﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using CRM.Index.Provider;
using System.Timers;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.Data.SqlClient;
using System.Collections.Concurrent;
using System.Data;
using CRM.DAL.SQLiteHelper;
using CRM.Entity;
using CRM.Index.Box;
using System.Data.SQLite;

namespace CRM.Index.Load
{
     public class Program
    {
        static void Main(string[] args)
        {
           using (ServiceHost host = new ServiceHost(typeof(ProviderService)))
            {
                try
                {
                    host.Open();

                    var watch = Stopwatch.StartNew();

                    //加载索引
                    new LoadHelper().Start();

                    Console.WriteLine("wcf内存数据全部加载！ 总共耗时:{0}", watch.ElapsedMilliseconds);

                    Console.Read();
                }
                catch (Exception)
                {
                    host.Close();
                    throw;
                }
            }
        }
    }

    public class LockMe
    {
        //默认的容纳大小为“硬件线程“数
        public static CountdownEvent cde = new CountdownEvent(Environment.ProcessorCount);
    }

    public class LoadHelper
    {
        SQLiteDataReader sr;

        int idCount;

        //一个线程读取5000条
        int smallID = 5000;

        int taskCount = 0;
        
        Stopwatch watch = new Stopwatch();

        public void Start()
        {
            #region UserInfo

             watch.Restart();

             sr = DbHelperSQL.ExecuteReader("select UserId from [UserInfo]");

            //数据库记录个数
            var idUserInfo = new List<Int64>();

            while (sr.Read())
                idUserInfo.Add(Convert.ToInt64(sr[0]));

            sr.Close();

            idCount = idUserInfo.Count;

            taskCount = idUserInfo.Count % smallID == 0 ? idUserInfo.Count / smallID : idUserInfo.Count / smallID + 1;

            Console.WriteLine("智能计算，UserInfo需要开启:{0} task,每个task加载:{1}条", taskCount, smallID);

            //重置信号
            LockMe.cde.Reset(taskCount);

            DictionaryBox.userInfoDictionary = new Dictionary<Int64, UserInfo>(idUserInfo.Count);

            DictionaryBox.userInfoUserIdSort = new SortedSet<Int64>(idUserInfo);

            for (int i = 0; i < taskCount; i++)
            {
                Task.Factory.StartNew((obj) =>
                {
                    new LoadEntity().LoadUserInfo(obj);

                }, idUserInfo.Skip(i * smallID).Take(smallID).ToList());
            }

            //等待所有任务执行完毕
            LockMe.cde.Wait();

            Console.WriteLine("\nUserInfo表数据全部加载完毕！总共加载：{0},耗时:{1}\n",DictionaryBox.userInfoUserIdSort.Count, watch.ElapsedMilliseconds);
         #endregion UserInfo
         
            #region ArticleType

             watch.Restart();

             sr = DbHelperSQL.ExecuteReader("select TypeId from [ArticleType]");

            //数据库记录个数
            var idArticleType = new List<Int64>();

            while (sr.Read())
                idArticleType.Add(Convert.ToInt64(sr[0]));

            sr.Close();

            idCount = idArticleType.Count;

            taskCount = idArticleType.Count % smallID == 0 ? idArticleType.Count / smallID : idArticleType.Count / smallID + 1;

            Console.WriteLine("智能计算，ArticleType需要开启:{0} task,每个task加载:{1}条", taskCount, smallID);

            //重置信号
            LockMe.cde.Reset(taskCount);

            DictionaryBox.articleTypeDictionary = new Dictionary<Int64, ArticleType>(idArticleType.Count);

            DictionaryBox.articleTypeTypeIdSort = new SortedSet<Int64>(idArticleType);

            for (int i = 0; i < taskCount; i++)
            {
                Task.Factory.StartNew((obj) =>
                {
                    new LoadEntity().LoadArticleType(obj);

                }, idArticleType.Skip(i * smallID).Take(smallID).ToList());
            }

            //等待所有任务执行完毕
            LockMe.cde.Wait();

            Console.WriteLine("\nArticleType表数据全部加载完毕！总共加载：{0},耗时:{1}\n",DictionaryBox.articleTypeTypeIdSort.Count, watch.ElapsedMilliseconds);
         #endregion ArticleType
         
            #region TextInfo

             watch.Restart();

             sr = DbHelperSQL.ExecuteReader("select TextId from [TextInfo]");

            //数据库记录个数
            var idTextInfo = new List<Int64>();

            while (sr.Read())
                idTextInfo.Add(Convert.ToInt64(sr[0]));

            sr.Close();

            idCount = idTextInfo.Count;

            taskCount = idTextInfo.Count % smallID == 0 ? idTextInfo.Count / smallID : idTextInfo.Count / smallID + 1;

            Console.WriteLine("智能计算，TextInfo需要开启:{0} task,每个task加载:{1}条", taskCount, smallID);

            //重置信号
            LockMe.cde.Reset(taskCount);

            DictionaryBox.textInfoDictionary = new Dictionary<Int64, TextInfo>(idTextInfo.Count);

            DictionaryBox.textInfoTextIdSort = new SortedSet<Int64>(idTextInfo);

            for (int i = 0; i < taskCount; i++)
            {
                Task.Factory.StartNew((obj) =>
                {
                    new LoadEntity().LoadTextInfo(obj);

                }, idTextInfo.Skip(i * smallID).Take(smallID).ToList());
            }

            //等待所有任务执行完毕
            LockMe.cde.Wait();

            Console.WriteLine("\nTextInfo表数据全部加载完毕！总共加载：{0},耗时:{1}\n",DictionaryBox.textInfoTextIdSort.Count, watch.ElapsedMilliseconds);
         #endregion TextInfo
         
            #region UserType

             watch.Restart();

             sr = DbHelperSQL.ExecuteReader("select UserTypeId from [UserType]");

            //数据库记录个数
            var idUserType = new List<Int64>();

            while (sr.Read())
                idUserType.Add(Convert.ToInt64(sr[0]));

            sr.Close();

            idCount = idUserType.Count;

            taskCount = idUserType.Count % smallID == 0 ? idUserType.Count / smallID : idUserType.Count / smallID + 1;

            Console.WriteLine("智能计算，UserType需要开启:{0} task,每个task加载:{1}条", taskCount, smallID);

            //重置信号
            LockMe.cde.Reset(taskCount);

            DictionaryBox.userTypeDictionary = new Dictionary<Int64, UserType>(idUserType.Count);

            DictionaryBox.userTypeUserTypeIdSort = new SortedSet<Int64>(idUserType);

            for (int i = 0; i < taskCount; i++)
            {
                Task.Factory.StartNew((obj) =>
                {
                    new LoadEntity().LoadUserType(obj);

                }, idUserType.Skip(i * smallID).Take(smallID).ToList());
            }

            //等待所有任务执行完毕
            LockMe.cde.Wait();

            Console.WriteLine("\nUserType表数据全部加载完毕！总共加载：{0},耗时:{1}\n",DictionaryBox.userTypeUserTypeIdSort.Count, watch.ElapsedMilliseconds);
         #endregion UserType
         
            #region ArticleInfo

             watch.Restart();

             sr = DbHelperSQL.ExecuteReader("select ArticleId from [ArticleInfo]");

            //数据库记录个数
            var idArticleInfo = new List<Int64>();

            while (sr.Read())
                idArticleInfo.Add(Convert.ToInt64(sr[0]));

            sr.Close();

            idCount = idArticleInfo.Count;

            taskCount = idArticleInfo.Count % smallID == 0 ? idArticleInfo.Count / smallID : idArticleInfo.Count / smallID + 1;

            Console.WriteLine("智能计算，ArticleInfo需要开启:{0} task,每个task加载:{1}条", taskCount, smallID);

            //重置信号
            LockMe.cde.Reset(taskCount);

            DictionaryBox.articleInfoDictionary = new Dictionary<Int64, ArticleInfo>(idArticleInfo.Count);

            DictionaryBox.articleInfoArticleIdSort = new SortedSet<Int64>(idArticleInfo);

            for (int i = 0; i < taskCount; i++)
            {
                Task.Factory.StartNew((obj) =>
                {
                    new LoadEntity().LoadArticleInfo(obj);

                }, idArticleInfo.Skip(i * smallID).Take(smallID).ToList());
            }

            //等待所有任务执行完毕
            LockMe.cde.Wait();

            Console.WriteLine("\nArticleInfo表数据全部加载完毕！总共加载：{0},耗时:{1}\n",DictionaryBox.articleInfoArticleIdSort.Count, watch.ElapsedMilliseconds);
         #endregion ArticleInfo
         
        }

        public class LoadEntity
        {
            #region UserInfo
            public void LoadUserInfo(object obj)
            {
                try
                {
                    var listID = obj as List<Int64>;

                    string sqlWhere = string.Join("','", listID);

                    var dt = DbHelperSQL.Query("select UserId,UserName,Password,UserType,CreateTime,LastLoginTime,Disable from [UserInfo] where UserId in ('" + sqlWhere + "')").Tables[0];

                    foreach (DataRow row in dt.Rows)
                    {
                       DictionaryBox.userInfoDictionary.Add(Convert.ToInt64(row["UserId"]),new UserInfo(row));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    LockMe.cde.Signal();
                }
            }
            #endregion UserInfo
            
            #region ArticleType
            public void LoadArticleType(object obj)
            {
                try
                {
                    var listID = obj as List<Int64>;

                    string sqlWhere = string.Join("','", listID);

                    var dt = DbHelperSQL.Query("select TypeId,TypeName,CreateTime,Disable from [ArticleType] where TypeId in ('" + sqlWhere + "')").Tables[0];

                    foreach (DataRow row in dt.Rows)
                    {
                       DictionaryBox.articleTypeDictionary.Add(Convert.ToInt64(row["TypeId"]),new ArticleType(row));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    LockMe.cde.Signal();
                }
            }
            #endregion ArticleType
            
            #region TextInfo
            public void LoadTextInfo(object obj)
            {
                try
                {
                    var listID = obj as List<Int64>;

                    string sqlWhere = string.Join("','", listID);

                    var dt = DbHelperSQL.Query("select TextId,TextKey,TextValue from [TextInfo] where TextId in ('" + sqlWhere + "')").Tables[0];

                    foreach (DataRow row in dt.Rows)
                    {
                       DictionaryBox.textInfoDictionary.Add(Convert.ToInt64(row["TextId"]),new TextInfo(row));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    LockMe.cde.Signal();
                }
            }
            #endregion TextInfo
            
            #region UserType
            public void LoadUserType(object obj)
            {
                try
                {
                    var listID = obj as List<Int64>;

                    string sqlWhere = string.Join("','", listID);

                    var dt = DbHelperSQL.Query("select UserTypeId,TypeName,Disable from [UserType] where UserTypeId in ('" + sqlWhere + "')").Tables[0];

                    foreach (DataRow row in dt.Rows)
                    {
                       DictionaryBox.userTypeDictionary.Add(Convert.ToInt64(row["UserTypeId"]),new UserType(row));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    LockMe.cde.Signal();
                }
            }
            #endregion UserType
            
            #region ArticleInfo
            public void LoadArticleInfo(object obj)
            {
                try
                {
                    var listID = obj as List<Int64>;

                    string sqlWhere = string.Join("','", listID);

                    var dt = DbHelperSQL.Query("select ArticleId,Title,ArticleType,Image,ArticleContent,CreateTime,CreateUser,ClickCount,Disable,IsNew,IsTop from [ArticleInfo] where ArticleId in ('" + sqlWhere + "')").Tables[0];

                    foreach (DataRow row in dt.Rows)
                    {
                       DictionaryBox.articleInfoDictionary.Add(Convert.ToInt64(row["ArticleId"]),new ArticleInfo(row));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                finally
                {
                    LockMe.cde.Signal();
                }
            }
            #endregion ArticleInfo
            

        }
    }
}